#ifndef __dbg_h__
#define __dbg_h__

/// This file is ONLY for debugging/logging/checking macros.
/// Do not add any other macros/functions/etc. which are used during computations.
/// K.Michalik - 10.2013 initial version

#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#ifdef PARALLEL
#include "pch_intf.h"
#endif

// For fast printing arrays.
#ifndef mf_print_array
#define mf_print_array(ar,size,typ) { for(int i=0; i < size; ++i){ printf(typ,ar[i]); printf(", "); } printf("\n"); }
#endif

// this macro is for showing only the filename, not full file path
#define MF_FILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)



#ifdef NDEBUG
# define mf_debug(M, ...)
# define mf_check_debug(A, M, ...)
# define mfp_debug(M, ...)
# define mfp_check_debug(A, M, ...)
#else
# define mf_debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", MF_FILE_NAME, __LINE__, ##__VA_ARGS__)
# define mf_check_debug(A, M, ...) if(!(A)) { mf_debug(M, ##__VA_ARGS__); assert(!M); }
# ifdef PARALLEL
#   define mfp_debug(M, ...) {int *idp = &pcv_my_proc_id; fprintf(stderr, "DEBUG[%d] %s:%d: " M "\n", *idp, MF_FILE_NAME, __LINE__, ##__VA_ARGS__); }
#   define mfp_check_debug(A, M, ...) if(!A) { mfp_debug(M, ##__VA_ARGS__); assert(!M); }
# else
#	define mfp_debug mf_debug
#	define mfp_check_debug mf_check_debug
# endif
#endif


#define mf_log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d ) " M "\n", MF_FILE_NAME, __LINE__, ##__VA_ARGS__)

#define mf_log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d ) " M "\n", MF_FILE_NAME, __LINE__, ##__VA_ARGS__)

#define mf_log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d ) " M "\n", MF_FILE_NAME, __LINE__, ##__VA_ARGS__)

#define mf_log_test_fail(M, ...) fprintf(stderr, "[TEST FAILED] (%s:%d ) " M "\n", MF_FILE_NAME, __LINE__, ##__VA_ARGS__)

#define mf_check(A, M, ...) if(!(A)) { mf_log_err(M, ##__VA_ARGS__); assert(!M); exit(-1);}

#define mf_sentinel(M, ...)  { mf_log_err(M, ##__VA_ARGS__); }

#define mf_check_mem(A) mf_check((A), "Out of memory.")

#define mf_check_info(A, M, ...) if(!(A)) { mf_log_info(M,##__VA_ARGS__); }

#define mf_test(A, M, ...) if(!(A)) { mf_log_test_fail(M, ##__VA_ARGS__); assert(!M);}

#endif // dbg.h
